using System;
using System.Collections.Generic;
using System.Linq;
using Phoenix.Framework;

namespace Phoenix.Filters
{
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
    public abstract class FilterAttribute : Attribute, IMvcFilter
    {
        private static readonly Dictionary<Type, bool> multiuseAttributeCache = new Dictionary<Type, bool>();
        private int order = Filter.DefaultOrder;
        static readonly object cacheLock = new object();

        public bool AllowMultiple
        {
            get { return AllowsMultiple(GetType()); }
        }

        public int Order
        {
            get { return order; }
            set
            {
                if (value < Filter.DefaultOrder)
                {
                    throw new ArgumentOutOfRangeException("value", "Order out of range");
                }
                order = value;
            }
        }

        private static bool AllowsMultiple(Type attributeType)
        {
            if (!multiuseAttributeCache.ContainsKey(attributeType))
            {
                lock(cacheLock)
                {
                    if (!multiuseAttributeCache.ContainsKey(attributeType))
                    {
                        var attributes = attributeType.GetCustomAttributes(typeof (AttributeUsageAttribute), true)
                            .Cast<AttributeUsageAttribute>()
                            .First()
                            .AllowMultiple;
                        multiuseAttributeCache.Add(attributeType, attributes);
                    }
                }
            }

            return multiuseAttributeCache[attributeType];
        }
    }
}